﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Configuration;
using Microsoft.SqlServer.ReportExecution;
using Microsoft.Reporting.WinForms;
using System.Data;
using System.Windows.Forms;
using System.Xml.Serialization;
using System.IO;

namespace SSRS_Plus
{
    public static class ReportWrapper
    {
        // declare variables
        public static SortedList AvailableServers;
        public static clsServers ActiveServer;
        public static clsServers SecondActiveServer;
        private static ReportExecutionService rsExecution;
        private static ReportingService2005 rsExplorer;
        private static ReportingService2005 rsSecondExplorer;
        public static string ServerDetails;
        private static DataTable dtFolders;
        private static DataTable dtDataSource;
        private static DataTable dtReports;
        private static DataTable dtSubscription;
        private static DataTable dtSnapshot;
        private static decimal ReportSize = 0.0M;
        private static decimal SnapshotSize = 0.0M;

        /// <summary>
        /// Return server list
        /// </summary>
        /// <returns></returns>
        public static void FillServerList()
        {
            ServersSection SerSec = (ServersSection)ConfigurationManager.GetSection("ServersSection");
            AvailableServers = new SortedList();

            int i = 0;

            while (i < SerSec.servergroups.Count)
            {
                clsServers Srv = new clsServers();

                Srv = (clsServers)SerSec.servergroups[i];
                AvailableServers.Add(Srv.ServerName, Srv);

                i++;
            }
        }

        /// <summary>
        /// Connect to server
        /// </summary>
        /// <param name="ServerName">Name of Server</param>
        /// <returns>True or False</returns>
        public static bool ConnectServer(string ServerName)
        {
            try
            {
                ActiveServer = new clsServers();
                ActiveServer = (clsServers)AvailableServers[ServerName];

                rsExecution = new ReportExecutionService();
                rsExplorer = new ReportingService2005();

                rsExecution.Url = ActiveServer.ServerURL.ToString();
                rsExplorer.Url = ActiveServer.ServerURL.ToString();

                if (ActiveServer.WindowsAuthentication == true)
                {
                    rsExecution.Credentials = System.Net.CredentialCache.DefaultCredentials;
                    rsExplorer.Credentials = System.Net.CredentialCache.DefaultCredentials;
                }
                else
                {
                    rsExecution.Credentials = new System.Net.NetworkCredential(ActiveServer.UserName, ActiveServer.Password, ActiveServer.Domain);
                    rsExplorer.Credentials = new System.Net.NetworkCredential(ActiveServer.UserName, ActiveServer.Password, ActiveServer.Domain);
                }

                FillServerObjects();
            }

            catch (Exception Ex)
            {
                throw Ex;
            }

            return false;
        }



        /// <summary>
        /// 
        /// </summary>
        /// <param name="ServerName"></param>
        /// <returns></returns>
        public static bool ConnectSecondServer(string ServerName)
        {
            try
            {
                SecondActiveServer = new clsServers();
                SecondActiveServer = (clsServers)AvailableServers[ServerName];

                rsSecondExplorer = new ReportingService2005();

                rsSecondExplorer.Url = SecondActiveServer.ServerURL.ToString();

                if (SecondActiveServer.WindowsAuthentication == true)
                {
                    rsSecondExplorer.Credentials = System.Net.CredentialCache.DefaultCredentials;
                }
                else
                {
                    rsSecondExplorer.Credentials = new System.Net.NetworkCredential(SecondActiveServer.UserName, SecondActiveServer.Password, SecondActiveServer.Domain);
                }
            }

            catch (Exception Ex)
            {
                throw Ex;
            }

            return false;
        }

        /// <summary>
        /// Fill Report details
        /// </summary>
        public static void FillServerObjects()
        {
            try
            {
                ReportSize = 0;
                int iFolders = 0, iReports = 0, iDataSource = 0;
                dtFolders = new DataTable();
                dtDataSource = new DataTable();
                dtReports = new DataTable();

                DataRow drFold;
                DataRow drDataSource;
                DataRow dr;

                dtFolders.Columns.Add("Folder Name");
                dtFolders.Columns.Add("Description");
                dtFolders.Columns.Add("Created On");
                dtFolders.Columns.Add("Created By");
                dtFolders.Columns.Add("Modified On");
                dtFolders.Columns.Add("Modified By");
                dtFolders.Columns.Add("Path");

                dtDataSource.Columns.Add("Name");
                dtDataSource.Columns.Add("Description");
                dtDataSource.Columns.Add("Created On");
                dtDataSource.Columns.Add("Created By");
                dtDataSource.Columns.Add("Modified On");
                dtDataSource.Columns.Add("Modified By");
                dtDataSource.Columns.Add("Path");

                dtReports.Columns.Add("ReportName");
                dtReports.Columns.Add("Size");
                dtReports.Columns.Add("Description");
                dtReports.Columns.Add("Created On");
                dtReports.Columns.Add("Created By");
                dtReports.Columns.Add("Modified On");
                dtReports.Columns.Add("Modified By");
                dtReports.Columns.Add("Path");
                dtReports.Columns[1].DataType = System.Type.GetType("System.Int32");

                foreach (CatalogItem ct in rsExplorer.ListChildren(@"/", true))
                {
                    if (ct.Type == ItemTypeEnum.Folder)
                    {
                        drFold = dtFolders.NewRow();
                        drFold[0] = ct.Name;
                        drFold[1] = ct.Description;
                        drFold[2] = ct.CreationDate.ToShortDateString();
                        drFold[3] = ct.CreatedBy;
                        drFold[4] = ct.ModifiedDate.ToShortDateString();
                        drFold[5] = ct.ModifiedBy;
                        drFold[6] = ct.Path;

                        dtFolders.Rows.Add(drFold);

                        iFolders++;
                    }
                    else if (ct.Type == ItemTypeEnum.DataSource)
                    {
                        drDataSource = dtDataSource.NewRow();
                        drDataSource[0] = ct.Name;
                        drDataSource[1] = ct.Description;
                        drDataSource[2] = ct.CreationDate.ToShortDateString();
                        drDataSource[3] = ct.CreatedBy;
                        drDataSource[4] = ct.ModifiedDate.ToShortDateString();
                        drDataSource[5] = ct.ModifiedBy;
                        drDataSource[6] = ct.Path;

                        dtDataSource.Rows.Add(drDataSource);

                        iDataSource++;
                    }
                    else if (ct.Type == ItemTypeEnum.Report || ct.Type == ItemTypeEnum.LinkedReport)
                    {
                        iReports++;
                        dr = dtReports.NewRow();
                        dr[0] = ct.Name;
                        dr[1] = ct.Size;
                        dr[2] = ct.Description;
                        dr[3] = ct.CreationDate.ToShortDateString();
                        dr[4] = ct.CreatedBy;
                        dr[5] = ct.ModifiedDate.ToShortDateString();
                        dr[6] = ct.ModifiedBy;
                        dr[7] = ct.Path;

                        dtReports.Rows.Add(dr);

                        ReportSize += ct.Size;
                    }
                }

                ServerDetails = "No of Folders = " + iFolders.ToString() + ", No of DataSources = " + iDataSource.ToString() + ", No of Reports = " + iReports.ToString();
            }
            catch
            {
                throw;
            }
        }

        /// <summary>
        /// Load dashboard details
        /// </summary>
        public static void LoadDashboard()
        {
            try
            {
                SnapshotSize = 0;

                dtSubscription = new DataTable();
                dtSnapshot = new DataTable();

                DataRow drSub;
                DataRow drSnap;

                dtSubscription.Columns.Add("ReportName");
                dtSubscription.Columns.Add("Subscription");
                dtSubscription.Columns.Add("ExecutionDate");
                dtSubscription.Columns.Add("Status");
                dtSubscription.Columns.Add("SubscriptioType");
                dtSubscription.Columns.Add("IsDataDriven");

                dtSnapshot.Columns.Add("ReportName");
                dtSnapshot.Columns.Add("HistoryID");
                dtSnapshot.Columns.Add("CreationDate");
                dtSnapshot.Columns.Add("Size");
                dtSnapshot.Columns[3].DataType = System.Type.GetType("System.Int32");

                foreach (CatalogItem ct in rsExplorer.ListChildren(@"/", true))
                {
                    if (ct.Type == ItemTypeEnum.Report || ct.Type == ItemTypeEnum.LinkedReport)
                    {
                        //worker.ReportProgress(1);

                        foreach (Subscription sub in rsExplorer.ListSubscriptions(ct.Path, null))
                        {
                            if (sub.LastExecuted > Convert.ToDateTime(DateTime.Now.AddDays(-7)))
                            {
                                drSub = dtSubscription.NewRow();
                                drSub[0] = sub.Report;
                                drSub[1] = sub.Description;
                                drSub[2] = sub.LastExecuted.ToShortDateString();
                                drSub[3] = sub.Status;
                                drSub[4] = sub.DeliverySettings.Extension;
                                drSub[5] = sub.IsDataDriven.ToString();

                                dtSubscription.Rows.Add(drSub);
                            }
                        }

                        //
                        foreach (ReportHistorySnapshot sn in rsExplorer.ListReportHistory(ct.Path))
                        {
                            SnapshotSize += sn.Size;

                            if (sn.CreationDate > Convert.ToDateTime(DateTime.Now.AddDays(-7)))
                            {
                                drSnap = dtSnapshot.NewRow();
                                drSnap[0] = ct.Name;
                                drSnap[1] = sn.HistoryID;
                                drSnap[2] = sn.CreationDate.ToShortDateString();
                                drSnap[3] = sn.Size;

                                dtSnapshot.Rows.Add(drSnap);
                            }
                        }
                    }
                }
            }
            catch
            {
                throw;
            }
        }

        /// <summary>
        /// Return most exectued reports on server.
        /// </summary>
        /// <returns>Data Table</returns>
        public static DataTable GetTopReportsinSize()
        {
            try
            {
                DataTable dt = dtReports.Clone();
                int i = 0;
                DataRow de;

                foreach (DataRow dr in dtReports.Select("Size > 0", "Size DESC"))
                {
                    de = dt.NewRow();
                    de[0] = dr[0];
                    de[1] = Decimal.Round(Convert.ToDecimal(dr[1]) / 1024.0M);

                    dt.Rows.Add(de);
                    i++;

                    if (i == 10)
                        break;
                }

                return dt;
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// Return Date wise Subscription and Snapshot run count
        /// </summary>
        /// <returns>Data Table</returns>
        public static DataTable GetSubscriptionVsSnapshot()
        {
            try
            {
                TimeSpan dateDiff;
                DateTime dtVar;

                DataTable dt = new DataTable();
                dt.Columns.Add("Date");
                dt.Columns.Add("Subcription");
                dt.Columns.Add("Snapshot");
                dt.Columns[1].DataType = System.Type.GetType("System.Int32");
                dt.Columns[2].DataType = System.Type.GetType("System.Int32");

                dtVar = DateTime.Now.AddDays(-7);

                dateDiff = (DateTime.Now - dtVar);

                for (int i = 1; i <= dateDiff.TotalDays; i++)
                {
                    DataRow dr = dt.NewRow();
                    string strDt = "'" + dtVar.AddDays(i).ToShortDateString() + "'";

                    int subCount = dtSubscription.Select("ExecutionDate = " + strDt).Count();
                    int snapCount = dtSnapshot.Select("CreationDate = " + strDt).Count();

                    if (subCount > 0 || snapCount > 0)
                    {
                        dr[0] = dtVar.AddDays(i).ToShortDateString();
                        dr[1] = subCount;
                        dr[2] = snapCount;

                        dt.Rows.Add(dr);
                    }
                }

                return dt;

            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// Get data for pai chart
        /// </summary>
        /// <returns>Data Table</returns>
        public static DataTable GetSizePaiChart()
        {
            try
            {
                DataTable dt = new DataTable();

                dt.Columns.Add("Entity");
                dt.Columns.Add("Size");
                dt.Columns[1].DataType = System.Type.GetType("System.Decimal");

                DataRow dr;

                dr = dt.NewRow();
                dr[0] = "Reports (MB)";
                dr[1] = Decimal.Round(((ReportSize / 1024.0M) / 1024.0M), 2);
                dt.Rows.Add(dr);

                dr = dt.NewRow();
                dr[0] = "Snapshot (MB)";
                dr[1] = Decimal.Round(((SnapshotSize / 1024.0M) / 1024.0M), 2);
                dt.Rows.Add(dr);

                return dt;

            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// Get Subscription details
        /// </summary>
        /// <returns>Data Table</returns>
        public static DataTable GetSubscriptions()
        {
            try
            {
                return dtSubscription;
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// Get Snapshot Details.
        /// </summary>
        /// <returns>Data Table</returns>
        public static DataTable GetSnapshotHistory()
        {
            try
            {
                return dtSnapshot;
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// Return Server Objects
        /// </summary>
        /// <returns>CatelogItem</returns>
        public static CatalogItem[] GetServerObjects()
        {
            try
            {
                return rsExplorer.ListChildren(@"/", true);
            }
            catch { return null; }
        }

        /// <summary>
        /// Get Item to download.
        /// </summary>
        /// <param name="ItemPath">Item Path</param>
        /// <param name="Type">Item Type</param>
        /// <returns>Byte[]</returns>
        public static byte[] DownloadItem(string ItemPath)
        {
            try
            {
                return rsExplorer.GetReportDefinition(ItemPath);
            }
            catch { return null; }
        }

        /// <summary>
        /// Get Item Details
        /// </summary>
        /// <param name="ItemPath"></param>
        /// <returns>StringBuilder</returns>
        public static StringBuilder GetItemDetails(string ItemPath)
        {
            try
            {
                StringBuilder details = new StringBuilder();

                string itemType = rsExplorer.GetItemType(ItemPath).ToString();

                if (itemType == ItemTypeEnum.Folder.ToString())
                {
                    bool inheritParent;

                    details.AppendLine("Folder Details:");
                    details.AppendLine("---------------------------------------");

                    foreach (DataRow dr in dtFolders.Select("Path ='" + ItemPath + "'"))
                    {
                        details.AppendLine("Name        : " + dr[0].ToString());
                        details.AppendLine("Description : " + dr[1].ToString());
                        details.AppendLine("Created On  : " + dr[2].ToString());
                        details.AppendLine("Created By  : " + dr[3].ToString());
                        details.AppendLine("Modified On : " + dr[4].ToString());
                        details.AppendLine("Modified By : " + dr[5].ToString());
                        details.AppendLine("Path        : " + dr[6].ToString());
                    }

                    details.AppendLine("---------------------------------------");
                    details.AppendLine("");

                    details.AppendLine("Permissions on this folder:");
                    details.AppendLine("---------------------------------------");

                    try
                    {
                        foreach (Policy pl in rsExplorer.GetPolicies(ItemPath, out inheritParent))
                        {
                            details.AppendLine("User/Group  : " + pl.GroupUserName);
                            int i = 0;
                            foreach (Role rl in pl.Roles)
                            {
                                if (i == 0)
                                    details.AppendLine("Permission  : " + rl.Name);
                                else
                                    details.AppendLine("              " + rl.Name);
                                i++;
                            }
                            details.AppendLine("");
                        }
                    }
                    catch { }

                    details.AppendLine("---------------------------------------");
                }
                else if (itemType == ItemTypeEnum.DataSource.ToString())
                {
                    DataSourceDefinition dsDef = rsExplorer.GetDataSourceContents(ItemPath);

                    details.AppendLine("Data Source Details:");
                    details.AppendLine("---------------------------------------");

                    foreach (DataRow dr in dtDataSource.Select("Path ='" + ItemPath + "'"))
                    {
                        details.AppendLine("Name                : " + dr[0].ToString());
                        details.AppendLine("Description         : " + dr[1].ToString());
                        details.AppendLine("Created On          : " + dr[2].ToString());
                        details.AppendLine("Created By          : " + dr[3].ToString());
                        details.AppendLine("Modified On         : " + dr[4].ToString());
                        details.AppendLine("Modified By         : " + dr[5].ToString());
                        details.AppendLine("Path                : " + dr[6].ToString());
                    }

                    details.AppendLine("Connection String   : " + dsDef.ConnectString);
                    details.AppendLine("Windows Credential  : " + dsDef.WindowsCredentials.ToString());
                    details.AppendLine("User Name           : " + dsDef.UserName);
                    details.AppendLine("Impersonate User    : " + dsDef.ImpersonateUser.ToString());

                    details.AppendLine("---------------------------------------");

                }
                else if (itemType == ItemTypeEnum.Report.ToString() || itemType == ItemTypeEnum.LinkedReport.ToString())
                {
                    details.AppendLine("Report Details:");
                    details.AppendLine("---------------------------------------");

                    foreach (DataRow dr in dtReports.Select("Path ='" + ItemPath + "'"))
                    {
                        details.AppendLine("Name          : " + dr[0].ToString());
                        details.AppendLine("Description   : " + dr[2].ToString());
                        details.AppendLine("Created On    : " + dr[3].ToString());
                        details.AppendLine("Created By    : " + dr[4].ToString());
                        details.AppendLine("Modified On   : " + dr[5].ToString());
                        details.AppendLine("Modified By   : " + dr[6].ToString());
                        details.AppendLine("Path          : " + dr[7].ToString());
                        details.AppendLine("Size          : " + decimal.Round(Convert.ToDecimal(dr[1]) / 1024.0M).ToString() + " KB");

                    }

                    foreach (DataSource ds in rsExplorer.GetItemDataSources(ItemPath))
                    {
                        details.AppendLine("Data Source   : " + ds.Name);
                        details.AppendLine("");

                        //foreach (Field fld in dsDef.Fields)
                        //{
                        //    dr = dtSub.NewRow();
                        //    dr[0] = fld.Name;
                        //    dr[1] = fld.Alias;
                        //    dr[2] = "DataSet Details";
                        //    dtSub.Rows.Add(dr);
                        //}

                    }

                    details.AppendLine("---------------------------------------");

                    Microsoft.SqlServer.ReportExecution.ReportParameter[] rpc = rsExplorer.GetReportParameters(ItemPath, null, false, null, null);

                    // Don't bother displaying empty Report Parameters section
                    if (rpc.Length > 0)
                    {
                        details.AppendLine("");
                        details.AppendLine("Report Parameters:");
                        details.AppendLine("---------------------------------------");


                        foreach (Microsoft.SqlServer.ReportExecution.ReportParameter rp in rpc)
                        {
                            details.AppendLine("Name          : " + rp.Name);
                            details.AppendLine("Prompt        : " + rp.Prompt);
                            details.AppendLine("Type          : " + rp.Type.ToString());
                            details.AppendLine("Nullable      : " + rp.Nullable.ToString());
                            details.AppendLine("Multivalue    : " + rp.MultiValue.ToString());
                            details.AppendLine("Allow Blank   : " + rp.AllowBlank.ToString());

                            if (rp.DefaultValues != null)
                                details.AppendLine("Default Values :" + string.Join(", ", rp.DefaultValues));

                            details.AppendLine("");
                        }

                        details.AppendLine("---------------------------------------");
                    }

                    details.AppendLine("");

                    Property[] p = GetReportExecutionSettings(ItemPath);
                    
                    details.AppendLine("Processing:");
                    details.AppendLine("---------------------------------------");

                    details.AppendLine("Execution Setting: " + p[0].Value);
                    details.AppendLine("Snapshots Stored : " + p[1].Value);

                    details.AppendLine("---------------------------------------");
                }

                return details;
            }

            catch { return null; }
        }

        /// <summary>
        /// Return execution settings for given report
        /// </summary>
        /// <param name="ReportPath"></param>
        /// <returns>Property[]</returns>
        public static Property[] GetReportExecutionSettings(string ReportPath)
        {
            ScheduleDefinitionOrReference unused;
            ExecutionSettingEnum setting = rsExplorer.GetExecutionOptions(ReportPath, out unused);
            bool keepExecutionSnapshots;
            rsExplorer.GetReportHistoryOptions(ReportPath, out keepExecutionSnapshots, out unused);

            Property[] p = new Property[2];
            p[0] = new Property();
            p[1] = new Property();
            p[0].Name = "Execution Setting";
            p[0].Value = setting.ToString();
            p[1].Name = "Store Snapshots";
            p[1].Value = keepExecutionSnapshots.ToString();

            return p;
        }

        /// <summary>
        /// Return all subcriptions for given report
        /// </summary>
        /// <param name="ReportPath"></param>
        /// <returns>Data Table</returns>
        public static DataTable GetSubscriptionForReport(String ReportPath)
        {
            try
            {
                DataTable dtSub = new DataTable("Sub");
                dtSub.Columns.Add("Subscription");
                dtSub.Columns.Add("Execution Date");
                dtSub.Columns.Add("Status");
                dtSub.Columns.Add("Data Driven");
                dtSub.Columns.Add("Subscription ID");
                dtSub.Columns.Add("Action");
                dtSub.Columns.Add("EventType");

                DataRow dr;

                foreach (Subscription sub in rsExplorer.ListSubscriptions(ReportPath, null))
                {
                    dr = dtSub.NewRow();
                    dr[0] = sub.Description;
                    dr[1] = sub.LastExecuted.ToShortDateString() + " " + sub.LastExecuted.ToShortTimeString();
                    dr[2] = sub.Status;
                    dr[3] = sub.IsDataDriven.ToString();
                    dr[4] = sub.SubscriptionID;
                    dr[5] = "Re-Run";
                    dr[6] = sub.EventType;

                    dtSub.Rows.Add(dr);

                }

                return dtSub;
            }
            catch { return null; }
        }

        /// <summary>
        /// Re-Run Subscription
        /// </summary>
        /// <param name="EventType">Event Type</param>
        /// <param name="EventData">Event Data</param>
        public static void RunSubscription(string EventType, String EventData)
        {
            try
            {
                rsExplorer.FireEvent(EventType, EventData);
            }
            catch { throw; }
        }

        /// <summary>
        /// Return all history snapshot for report.
        /// </summary>
        /// <param name="ReportPath">Report Path</param>
        /// <returns>Data Table</returns>
        public static DataTable GetSnapshotForReport(String ReportPath)
        {
            try
            {
                DataTable dtSub = new DataTable("Sub");
                dtSub.Columns.Add("History ID");
                dtSub.Columns.Add("Creation Date");
                dtSub.Columns.Add("Size");

                DataRow dr;

                foreach (ReportHistorySnapshot sub in rsExplorer.ListReportHistory(ReportPath))
                {
                    dr = dtSub.NewRow();
                    dr[0] = sub.HistoryID;
                    dr[1] = sub.CreationDate.ToShortDateString() + " " + sub.CreationDate.ToShortTimeString();
                    dr[2] = sub.Size;

                    dtSub.Rows.Add(dr);
                }

                return dtSub;
            }
            catch { return null; }
        }

        /// <summary>
        /// Get Supported Render Extensions
        /// </summary>
        /// <returns>String[]</returns>
        public static string[] GetSupportedExtensions()
        {
            try
            {
                string[] str = new string[Convert.ToInt32(rsExplorer.ListExtensions(ExtensionTypeEnum.Render).Count())];
                int i = 0;

                foreach (Extension ext in rsExplorer.ListExtensions(ExtensionTypeEnum.Render))
                {
                    str[i] = ext.Name;

                    i++;
                }

                return str;
            }

            catch { return null; }
        }

        /// Delete specific snapshots
        /// </summary>
        /// <param name="HistoryID"></param>
        public static void DeleteSnapshot(string Report, string HistoryID)
        {
            try
            {
                rsExplorer.DeleteReportHistorySnapshot(Report, HistoryID);
            }
            catch { };
        }

        /// Update report snapshots
        /// </summary>
        /// <param name="Report"></param>
        public static void UpdateSnapshot(string Report)
        {
            try
            {
                rsExplorer.UpdateReportExecutionSnapshot(Report);
            }
            catch { };
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static CatalogItem[] GetSecondServerObjects()
        {
            try
            {
                return rsSecondExplorer.ListChildren(@"/", true);
            }
            catch { return null; }
        }

        /// <summary>
        /// Copy report from one server to another.
        /// </summary>
        /// <param name="SourceReportPath">Source Report Path</param>
        /// <param name="ReportName">Report Name</param>
        /// <param name="DestinationFolder">Destinatio Folder</param>
        public static void CopyItem(string SourceReportPath, string ReportName, string DestinationFolder)
        {
            try
            {
                rsSecondExplorer.CreateReport(ReportName, DestinationFolder, true, rsExplorer.GetReportDefinition(SourceReportPath), null);
            }
            catch { };
        }


        /// <summary>
        /// Set Data Source to report
        /// </summary>
        /// <param name="report">Report Path</param>
        /// <param name="dataSet">Dataset Path</param>
        public static void SetDataSource(string report, string dataSet)
        {
            try
            {
                DataSourceReference rs = new DataSourceReference();
                DataSource ds = new DataSource();
                rs.Reference = dataSet;
                ds.Item = (DataSourceDefinitionOrReference)rs;

                DataSource[] dsArr = new DataSource[1];
                DataSource[] reportDataSource = rsSecondExplorer.GetItemDataSources(report);

                ds.Name = reportDataSource[0].Name;
                //ds.Name = dataSet;//.Substring(dataSet.LastIndexOf(@"/") + 1, dataSet.Length - dataSet.LastIndexOf(@"/") - 1);
                dsArr[0] = ds;

                rsSecondExplorer.SetItemDataSources(report, dsArr);

            }
            catch { };

        }

        /// <summary>
        /// Get Subscription Details
        /// </summary>
        /// <param name="SubscriptionID">Subscription ID</param>
        /// <param name="Type">Type i.e. Data Driven or Email</param>
        /// <returns>Data Table</returns>
        public static DataTable GetSubscriptionParameter(string SubscriptionID, string Type)
        {
            try
            {
                ExtensionSettings ex = null;
                DataRetrievalPlan dp = null;
                string s1;
                string s2;
                string s3;
                string s4;
                ActiveState as1 = null;
                ParameterValueOrFieldReference[] fd = null;
                ParameterValue[] pv = null;

                DataTable dtSub = new DataTable();
                dtSub.Columns.Add("Paramerter");
                dtSub.Columns.Add("Value");
                dtSub.Columns.Add("Type");

                DataRow dr;

                if (Type == "True")
                    rsExplorer.GetDataDrivenSubscriptionProperties(SubscriptionID, out ex, out dp, out s1, out as1, out s2, out s3, out s4, out fd);
                else
                    rsExplorer.GetSubscriptionProperties(SubscriptionID, out ex, out s1, out as1, out s2, out s3, out s4, out pv);

                DataSetDefinition dsDef = dp.DataSet;
                foreach (Field fld in dsDef.Fields)
                {
                    dr = dtSub.NewRow();
                    dr[0] = fld.Name;
                    dr[1] = fld.Alias;
                    dr[2] = "DataSet Details";
                    dtSub.Rows.Add(dr);
                }

                foreach (ParameterValueOrFieldReference p1 in ex.ParameterValues)
                {
                    if (p1.GetType().Name == "ParameterFieldReference")
                    {
                        ParameterFieldReference pf1 = (ParameterFieldReference)p1;

                        dr = dtSub.NewRow();
                        dr[0] = pf1.ParameterName;
                        dr[1] = pf1.FieldAlias;
                        dr[2] = "Subscription Fields";
                        dtSub.Rows.Add(dr);
                    }
                    else
                    {
                        ParameterValue pv1 = (ParameterValue)p1;

                        dr = dtSub.NewRow();
                        dr[0] = pv1.Name;
                        dr[1] = pv1.Value;
                        dr[2] = "Subscription Fields";
                        dtSub.Rows.Add(dr);
                    }
                }

                return dtSub;
            }
            catch { return null; }
        }

        /// <summary>
        /// Get Data for report
        /// </summary>
        /// <returns>Data Table</returns>
        public static DataTable GetReportData()
        {
            try
            {
                DataTable dtReportData = new DataTable();
                DataRow dr;

                dtReportData.Columns.Add("Parameter1");
                dtReportData.Columns.Add("Value1");
                dtReportData.Columns.Add("Parameter2");
                dtReportData.Columns.Add("Value2");
                dtReportData.Columns.Add("Type");
                dtReportData.Columns.Add("Group");
                dtReportData.Columns.Add("Group2");

                dr = dtReportData.NewRow();
                dr[0] = "Edition";
                dr[1] = rsExplorer.ServerInfoHeaderValue.ReportServerEdition;
                dr[2] = "Version";
                dr[3] = rsExplorer.ServerInfoHeaderValue.ReportServerVersion + " " + rsExplorer.ServerInfoHeaderValue.ReportServerVersionNumber;
                dr[4] = "Server";
                dtReportData.Rows.Add(dr);

                dr = dtReportData.NewRow();
                dr[0] = "URL";
                dr[1] = rsExplorer.Url;
                dr[2] = "Server Date Time";
                dr[3] = rsExplorer.ServerInfoHeaderValue.ReportServerDateTime;
                dr[4] = "Server";
                dtReportData.Rows.Add(dr);

                int i = 0;
                foreach (Property pr in rsExplorer.GetSystemProperties(null))
                {
                    if (i % 2 == 0)
                    {
                        dr = dtReportData.NewRow();
                        dr[0] = pr.Name;
                        dr[1] = pr.Value;
                    }
                    else
                    {
                        dr[2] = pr.Name;
                        dr[3] = pr.Value;
                        dr[4] = "Server";
                        dtReportData.Rows.Add(dr);
                    }
                    i++;
                }

                if (rsExplorer.GetSystemProperties(null).Count() % 2 != 0)
                {
                    dr[4] = "Server";
                    dtReportData.Rows.Add(dr);
                }

                dr = dtReportData.NewRow();
                dr[0] = "Policies";
                dr[4] = "Server";
                dtReportData.Rows.Add(dr);

                StringBuilder str = new StringBuilder();
                i = 0;

                try
                {
                    foreach (Policy pr in rsExplorer.GetSystemPolicies())
                    {
                        if (i % 2 == 0)
                        {
                            dr = dtReportData.NewRow();
                            dr[0] = pr.GroupUserName;

                            foreach (Role rl in pr.Roles)
                                str.AppendLine(rl.Name);

                            dr[1] = str;
                        }
                        else
                        {
                            str.Remove(0, str.Length - 1);
                            dr[2] = pr.GroupUserName;

                            foreach (Role rl in pr.Roles)
                                str.AppendLine(rl.Name);
                            dr[3] = str.ToString().Trim();
                            dr[4] = "Server";
                            dtReportData.Rows.Add(dr);
                        }
                        i++;
                    }
                }
                catch { }

                //Folder structure
                bool inheritParent;
                i = 0;

                foreach (DataRow dr1 in dtFolders.Rows)
                {
                    dr = dtReportData.NewRow();
                    dr[0] = dr1[0].ToString();
                    dr[1] = dr1[1].ToString();
                    dr[2] = dr1[6].ToString();
                    dr[3] = dr1[2].ToString();
                    dr[4] = "Folder";
                    dtReportData.Rows.Add(dr);

                    if (str.Length != 0)
                        str.Remove(0, str.Length - 1);

                    try
                    {
                        foreach (Policy pl in rsExplorer.GetPolicies(dr1[6].ToString(), out inheritParent))
                        {

                            dr = dtReportData.NewRow();
                            dr[0] = pl.GroupUserName;

                            foreach (Role rl in pl.Roles)
                                str.AppendLine(rl.Name);

                            dr[2] = dr1[6].ToString();

                            dr[1] = str.ToString().Trim();
                            dr[4] = "FolderDetails";
                            dtReportData.Rows.Add(dr);
                        }
                    }
                    catch { }
                }

                //Data Sources structure
                foreach (DataRow dr1 in dtDataSource.Rows)
                {
                    dr = dtReportData.NewRow();
                    dr[0] = dr1[0].ToString();
                    dr[1] = dr1[1].ToString();
                    dr[2] = dr1[6].ToString();
                    dr[4] = "DataSource";
                    dr[5] = dr1[6].ToString();
                    dtReportData.Rows.Add(dr);

                    dr = dtReportData.NewRow();
                    dr[0] = "Created On";
                    dr[1] = dr1[2].ToString();
                    dr[2] = "Created By";
                    dr[3] = dr1[3].ToString();
                    dr[4] = "DataSourceDetails";
                    dr[5] = dr1[6].ToString();
                    dtReportData.Rows.Add(dr);

                    dr = dtReportData.NewRow();
                    dr[0] = "Modified On";
                    dr[1] = dr1[4].ToString();
                    dr[2] = "Modified By";
                    dr[3] = dr1[5].ToString();
                    dr[4] = "DataSourceDetails";
                    dr[5] = dr1[6].ToString();
                    dtReportData.Rows.Add(dr);

                    DataSourceDefinition dsDef = rsExplorer.GetDataSourceContents(dr1[6].ToString());

                    if (dsDef != null)
                    {
                        dr = dtReportData.NewRow();
                        dr[0] = "Connection";
                        dr[1] = dsDef.ConnectString;
                        dr[2] = "Windows Credential";
                        dr[3] = dsDef.WindowsCredentials.ToString();
                        dr[4] = "DataSourceDetails";
                        dr[5] = dr1[6].ToString();
                        dtReportData.Rows.Add(dr);

                        dr = dtReportData.NewRow();
                        dr[0] = "User Name";
                        dr[1] = dsDef.UserName;
                        dr[2] = "Impersonate User";
                        dr[3] = dsDef.ImpersonateUser;
                        dr[4] = "DataSourceDetails";
                        dr[5] = dr1[6].ToString();
                        dtReportData.Rows.Add(dr);
                    }
                }

                //Report Details
                foreach (DataRow dr1 in dtReports.Rows)
                {
                    string reportLink = ReportWrapper.ActiveServer.ServerURL.ToString().Substring(1, ReportWrapper.ActiveServer.ServerURL.ToString().LastIndexOf("/") - 1);
                    reportLink = "h" + reportLink.ToUpper().Replace("REPORTSERVER", "REPORTS").ToLower() + "/Pages/Report.aspx?ItemPath=";
                    reportLink = reportLink + dr1[7].ToString().Replace("/", "%2f").Replace(" ", "+");

                    dr = dtReportData.NewRow();
                    dr[0] = dr1[0].ToString();
                    dr[1] = dr1[2].ToString();
                    dr[2] = decimal.Round(Convert.ToDecimal(dr1[1]) / 1024.0M).ToString() + " KB";
                    dr[4] = "Report";
                    dr[5] = reportLink;

                    try
                    {
                        foreach (DataSource ds in rsExplorer.GetItemDataSources(dr1[7].ToString()))
                        {

                            if (ds.Item.GetType().Name == "DataSourceDefinition")
                            {
                                DataSourceDefinition df = (DataSourceDefinition)ds.Item;
                                dr[3] = df.ConnectString;
                            }
                            else
                            {
                                DataSourceReference df = (DataSourceReference)ds.Item;
                                dr[3] = df.Reference;
                            }
                        }

                        dtReportData.Rows.Add(dr);
                    }
                    catch { }
                    foreach (Microsoft.SqlServer.ReportExecution.ReportParameter rp in rsExplorer.GetReportParameters(dr1[7].ToString(), null, false, null, null))
                    {
                        dr = dtReportData.NewRow();
                        dr[0] = "Name";
                        dr[1] = rp.Name;
                        dr[2] = "Prompt";
                        dr[3] = rp.Prompt;
                        dr[4] = "ReportParameter";
                        dr[5] = reportLink;
                        dr[6] = rp.Name;
                        dtReportData.Rows.Add(dr);

                        dr = dtReportData.NewRow();
                        dr[0] = "Type";
                        dr[1] = rp.Type;
                        dr[2] = "Nullable";
                        dr[3] = rp.Nullable.ToString();
                        dr[4] = "ReportParameter";
                        dr[5] = reportLink;
                        dr[6] = rp.Name;
                        dtReportData.Rows.Add(dr);

                        dr = dtReportData.NewRow();
                        dr[0] = "Multivalue";
                        dr[1] = rp.MultiValue.ToString();
                        dr[2] = "Allow Blank";
                        dr[3] = rp.AllowBlank.ToString();
                        dr[4] = "ReportParameter";
                        dr[5] = reportLink;
                        dr[6] = rp.Name;
                        dtReportData.Rows.Add(dr);

                        dr = dtReportData.NewRow();
                        dr[0] = "Default Value(s)";

                        if (rp.DefaultValues != null)
                            dr[1] = string.Join(", ", rp.DefaultValues);

                        dr[4] = "ReportParameter";
                        dr[5] = reportLink;
                        dr[6] = rp.Name;
                        dtReportData.Rows.Add(dr);

                    }

                    i = 0;
                    foreach (Property pr in rsExplorer.GetProperties(dr1[7].ToString(), null))
                    {
                        if (i % 2 == 0)
                        {
                            dr = dtReportData.NewRow();
                            dr[0] = pr.Name;
                            dr[1] = pr.Value;
                        }
                        else
                        {
                            dr[2] = pr.Name;
                            dr[3] = pr.Value;
                            dr[4] = "ReportProperties";
                            dr[5] = reportLink;
                            dr[6] = "Properties";
                            dtReportData.Rows.Add(dr);
                        }
                        i++;
                    }

                    if (rsExplorer.GetProperties(dr1[7].ToString(), null).Count() % 2 != 0)
                    {
                        dr[4] = "ReportProperties";
                        dr[5] = reportLink;
                        dr[6] = "Properties";
                        dtReportData.Rows.Add(dr);
                    }

                     //add subscription details
                    foreach (Subscription sub in rsExplorer.ListSubscriptions(dr1[7].ToString(), null))
                    {
                        dr = dtReportData.NewRow();
                        dr[0] = dr1[0].ToString();
                        dr[1] = sub.Description;
                        dr[2] = sub.DeliverySettings.Extension;
                        dr[3] = sub.IsDataDriven.ToString();
                        dr[4] = "Subscription";
                        dr[5] = dr1[0].ToString();
                        dr[6] = sub.Description;
                        dtReportData.Rows.Add(dr);

                        dr = dtReportData.NewRow();
                        dr[0] = "Last Executed";
                        dr[1] = sub.LastExecuted.ToShortDateString() + " " + sub.LastExecuted.ToShortTimeString();
                        dr[2] = "Status";
                        dr[3] = sub.Status;
                        dr[4] = "SubscriptionProperties";
                        dr[5] = dr1[0].ToString();
                        dr[6] = sub.Description;
                        dtReportData.Rows.Add(dr);

                        ExtensionSettings ex = null;
                        DataRetrievalPlan dp = null;
                        string s1;
                        string s2;
                        string s3;
                        string s4;
                        ActiveState as1 = null;
                        ParameterValueOrFieldReference[] fd = null;
                        ParameterValue[] pv = null;

                        if (sub.IsDataDriven)
                            rsExplorer.GetDataDrivenSubscriptionProperties(sub.SubscriptionID, out ex, out dp, out s1, out as1, out s2, out s3, out s4, out fd);
                        else
                            rsExplorer.GetSubscriptionProperties(sub.SubscriptionID, out ex, out s1, out as1, out s2, out s3, out s4, out pv);

                        i = 0;

                        foreach (ParameterValueOrFieldReference p1 in ex.ParameterValues)
                        {
                            string param, val;

                            if (p1.GetType().Name == "ParameterFieldReference")
                            {
                                ParameterFieldReference pf1 = (ParameterFieldReference)p1;
                                param = pf1.ParameterName;
                                val = pf1.FieldAlias;
                            }
                            else
                            {
                                ParameterValue pv1 = (ParameterValue)p1;
                                param = pv1.Name;
                                val = pv1.Value;
                            }

                            if (i % 2 == 0)
                            {
                                dr = dtReportData.NewRow();
                                dr[0] = param;
                                dr[1] = val;
                            }
                            else
                            {
                                dr[2] = param;
                                dr[3] = val;
                                dr[4] = "SubscriptionProperties";
                                dr[5] = dr1[0].ToString();
                                dr[6] = sub.Description;
                                dtReportData.Rows.Add(dr);
                            }
                            i++;
                        }

                        if (ex.ParameterValues.Count() % 2 != 0)
                        {
                            dr[4] = "SubscriptionProperties";
                            dr[5] = dr1[0].ToString();
                            dr[6] = sub.Description;
                            dtReportData.Rows.Add(dr);
                        }

                        if (dp != null)
                        {
                            DataSetDefinition dsDef = dp.DataSet;
                            QueryDefinition qf = dsDef.Query;

                            dr = dtReportData.NewRow();
                            dr[0] = "Query Type";
                            dr[1] = qf.CommandType;
                            dr[2] = "Query Text";
                            dr[3] = qf.CommandText;
                            dr[4] = "SubscriptionProperties";
                            dr[5] = dr1[0].ToString();
                            dr[6] = sub.Description;
                            dtReportData.Rows.Add(dr);
                        }

                        //string str1 = "encoding=\"utf-16\"";
                        //ScheduleDefinition sc = DeserializeObject(s4.Replace(str1,""));

                    }
                }

                return dtReportData;
            }
            catch
            {
                return null;
            }
        }

        private static XmlAttributeOverrides GetScheduleOverrides()
        {
            XmlAttributeOverrides overrides = new XmlAttributeOverrides();
            XmlAttributes attrs = new XmlAttributes();
            attrs.Xmlns = false;
            overrides.Add(typeof(ScheduleDefinition), attrs);
            overrides.Add(typeof(MinuteRecurrence), attrs);
            overrides.Add(typeof(WeeklyRecurrence), attrs);
            overrides.Add(typeof(MonthlyRecurrence), attrs);
            overrides.Add(typeof(MonthlyDOWRecurrence), attrs);
            overrides.Add(typeof(DaysOfWeekSelector), attrs);
            overrides.Add(typeof(MonthsOfYearSelector), attrs);
            return overrides;
        }

        private static ScheduleDefinition DeserializeObject(string sMatchData)
        {
            sMatchData = sMatchData.Replace("True", "true");
            Stream stream = new
            MemoryStream(System.Text.Encoding.Default.GetBytes(sMatchData));

            XmlAttributeOverrides overrides = GetScheduleOverrides();
            XmlSerializer ser = new XmlSerializer(typeof(ScheduleDefinition),
            overrides);

            stream.Position = 0;
            return (ScheduleDefinition)ser.Deserialize(stream);
        }
    }
}
